/*
 * $Log: $
 */
package com.rock.code.datacollconfig.coll.service;


import com.rock.code.common.util.CollSchedulerFactory;
import com.rock.code.datacollconfig.coll.condition.DataCollCondition;
import com.rock.code.datacollconfig.coll.domain.DataColl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Title: DataCollInstanceThread<br>
 * Description: <br>
 * 线程遍历采集表，定时采集数据
 * @author wangsla
 * @date 2013.1.7
 */
@Component
public class DataCollInstanceThread extends Thread {
	@Autowired
	private IDataCollService dataCollService;
	private Log logger = LogFactory.getLog(getClass());
	private int frequency = 20;

	public DataCollInstanceThread() {
	}

	public DataCollInstanceThread(int frequency) {
		this.frequency = frequency;
	}

	public void run() {
		super.run();
		Scheduler scheduler = null;
		try {
			scheduler = CollSchedulerFactory.getScheduler();
			DataCollCondition condition = new DataCollCondition();
			String[] queryCollStatus = new String[] { DataColl.COLLSTATUS_JOINTASK };
			condition.setQueryCollStatus(queryCollStatus);
			List<DataColl> dataCollList =
					dataCollService.listDataCollByCondition(condition);
			initDataCollSchedule(scheduler, dataCollList);
			scheduler.start();
			int flag = 0;
			while (true) {
				super.run();
				try {
					Thread.sleep(1000 * this.frequency);
					queryCollStatus = new String[] {
							DataColl.COLLSTATUS_NOTJOINTASK,
							DataColl.COLLSTATUS_JOINTASK,
							DataColl.COLLSTATUS_JOINTASKMODIFY };
					condition.setQueryCollStatus(queryCollStatus);
					
					dataCollList = dataCollService.listDataCollByCondition(condition);
					for (DataColl dataColl : dataCollList) { //遍历采集集合
						String id = dataColl.getId();
						Date startTime = returnDateByString(dataColl
								.getCollTimeStartEffectiveDate(),
								"yyyy-MM-dd HH:mm:ss"); // 采集有效开始时间
						Date endTime = returnDateByString(dataColl
								.getCollTimeEndEffectiveDate(),
								"yyyy-MM-dd HH:mm:ss"); // 采集有效结束时间
						flag = executeFlagByStartAndEndTime(startTime, endTime,
								new Date());
						if (dataColl.getCollStatus().equals(
								DataColl.COLLSTATUS_NOTJOINTASK)) { // 如果是未加入定时任务
							if (flag == 1) { // 当前时间在采集有效时间之内
								// 添加定时任务
								this.addScheduleJob(scheduler, id, dataColl
										.getCollTimeExpr());
								// 更新采集标识位
								DataColl updateDataColl = new DataColl();
								updateDataColl.setId(id);
								updateDataColl
										.setCollStatus(DataColl.COLLSTATUS_JOINTASK);
								dataCollService.updateDataColl(updateDataColl);
							}
							if (flag == 3) { // 当前时间已超过采集有效时间
								// 更新采集标识位
								DataColl updateDataColl = new DataColl();
								updateDataColl.setId(id);
								updateDataColl
										.setCollStatus(DataColl.COLLSTATUS_COMPLETE);
								dataCollService.updateDataColl(updateDataColl);
							}
						} else if (dataColl.getCollStatus().equals(
								DataColl.COLLSTATUS_JOINTASK)) { // 如果是已加入定时任务的采集
							if (flag == 3) { // 超过采集有效时间
								// 删除定时任务
								deleteScheduleJob(scheduler, id);
								
								// 更新采集标识位
								DataColl updateDataColl = new DataColl();
								updateDataColl.setId(id);
								updateDataColl
										.setCollStatus(DataColl.COLLSTATUS_COMPLETE);
								dataCollService.updateDataColl(updateDataColl);
							}
						} else if (dataColl.getCollStatus().equals(
								DataColl.COLLSTATUS_JOINTASKMODIFY)) { // 如果是采集过程中被修改的采集
							// 删除已有的定时任务
							deleteScheduleJob(scheduler, id);
							
							// 更新采集标识位
							DataColl updateDataColl = new DataColl();
							updateDataColl.setId(id);
							updateDataColl
									.setCollStatus(DataColl.COLLSTATUS_NOTJOINTASK);
							dataCollService.updateDataColl(updateDataColl);
						}
					}
				} catch (Throwable throwable) {
					logger.error("定时采集数据项出现异常！");
					throwable.printStackTrace();
					scheduler = CollSchedulerFactory.getScheduler();
					scheduler.start();
				}
			}
		} catch (SchedulerException schedulerException) {
			schedulerException.printStackTrace();
		} catch (ParseException parseException) {
			parseException.printStackTrace();
		}
	}

	/**
	 * 初始化采集定时任务
	 * 
	 * @param scheduler
	 * @param dataCollList
	 * @throws ParseException
	 * @throws SchedulerException
	 * wangsla 修改 2013.1.7
	 */
	public void initDataCollSchedule(Scheduler scheduler,
			List<DataColl> dataCollList) throws ParseException,
            SchedulerException {
		for (DataColl dataColl : dataCollList) {
			String id = dataColl.getId();
			Date startTime = returnDateByString(dataColl
					.getCollTimeStartEffectiveDate(), "yyyy-MM-dd HH:mm:ss");
			Date endTime = returnDateByString(dataColl
					.getCollTimeEndEffectiveDate(), "yyyy-MM-dd HH:mm:ss");
			int flag = executeFlagByStartAndEndTime(startTime, endTime,
					new Date());
			if (flag == 1) {
				String scheduleTime = dataColl.getCollTimeExpr();
				this.addScheduleJob(scheduler, id, scheduleTime);
				DataColl updateDataColl = new DataColl();
				updateDataColl.setId(id);
				updateDataColl.setCollStatus(DataColl.COLLSTATUS_JOINTASK);
				dataCollService.updateDataColl(updateDataColl);
			}
		}
	}

	/**
	 * 增加定时任务
	 * 
	 * @param scheduler
	 * @param jobId
	 * @param cronScheduleTime
	 * @throws ParseException
	 * @throws SchedulerException
	 * @author Huosd
	 * @date May 25, 2012
	 */
	public void addScheduleJob(Scheduler scheduler, String jobId,
                               String cronScheduleTime) throws ParseException, SchedulerException {
		JobKey jobKey = new JobKey("job_" + jobId, "group_" + jobId);
		JobDetail jobDetail = JobBuilder.newJob(DataCollInstanceJob.class).withIdentity(jobKey).build();
		jobDetail.getJobDataMap().put("ID", jobId);

		TriggerKey triggerKey = new TriggerKey("trigger_" + jobId,
				"trigger_group_" + jobId);

		Trigger cronTrigger =  TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(CronScheduleBuilder.cronSchedule(cronScheduleTime)).build();

		scheduler.scheduleJob(jobDetail, cronTrigger);
		logger.info("addScheduleJob____jobId=" + jobId);
	}

	/**
	 * 删除定时任务
	 * 
	 * @param scheduler
	 * @param jobId
	 * @throws SchedulerException
	 * @author Huosd
	 * @date May 25, 2012
	 */
	public void deleteScheduleJob(Scheduler scheduler, String jobId)
			throws SchedulerException {
		JobKey jobKey = new JobKey("job_" + jobId, "group_" + jobId);
		scheduler.deleteJob(jobKey);
		logger.info("deleteScheduleJob_____jobId=" + jobId);
	}

	/**
	 * 判断当前时间和定时任务有效时间的关系
	 * 
	 * @param startTime
	 * @param endTime
	 * @param nowDate
	 * @return
	 * @author Huosd
	 * @date May 25, 2012
	 */
	public int executeFlagByStartAndEndTime(Date startTime, Date endTime,
                                            Date nowDate) {
		// 当前时间在开始时间和结束时间内,返回1
		// 当前时间早于开始时间,则不作任何处理，返回2
		// 当前时间晚于最晚时间,则在调度的日历中把该job去掉,但是不删除表中的记录 返回值为3
		if (nowDate.before(endTime) && nowDate.after(startTime))
			return 1;
		if (nowDate.before(startTime))
			return 2;
		if (nowDate.after(endTime))
			return 3;
		return 0;
	}


	/**
	 * 通过字符串型时间参数返回Date类型
	 *
	 * @param date
	 * @param format
	 * @return
	 * @throws ParseException
	 * @author Huosd
	 * @date Apr 23, 2012
	 */
	public static Date returnDateByString(String date, String format)
			throws ParseException {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
		return simpleDateFormat.parse(date);
	}

	public IDataCollService getDataCollService() {
		return dataCollService;
	}

	public void setDataCollService(IDataCollService dataCollService) {
		this.dataCollService = dataCollService;
	}
}
